package com.company.cloud.user.client;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.company.cloud.common.asserts.ValidatorUtils;
import com.company.cloud.common.bean.BaseClientResult;
import com.company.cloud.common.bean.LoginSimpleUserInfo;
import com.company.cloud.common.constant.BaseConstant;
import com.company.cloud.user.constant.UserConstant;
import com.company.cloud.user.modules.api.request.RoleAddRequest;
import com.company.cloud.user.modules.api.request.RoleGet2DelRequest;
import com.company.cloud.user.modules.api.request.RoleQueryRequest;
import com.company.cloud.user.modules.api.request.RoleUpdateRequest;
import com.company.cloud.user.modules.api.response.RoleModel;
import com.company.cloud.user.modules.api.response.UserBaseResp;
import com.company.cloud.user.modules.api.service.RolePlatformRemoteService;
import com.company.cloud.user.modules.base.entity.RoleInfo;
import com.company.cloud.user.modules.base.entity.RolePermissionInfo;
import com.company.cloud.user.modules.base.entity.UserRoleInfo;
import com.company.cloud.user.modules.base.service.RoleInfoService;
import com.company.cloud.user.modules.base.service.RolePermissionInfoService;
import com.company.cloud.user.modules.base.service.UserRoleInfoService;
import com.company.cloud.user.modules.cache.service.UserPermissionCacheService;
import com.company.cloud.user.modules.cache.utils.UserConvertUtils;
import com.company.cloud.user.modules.mgr.controller.req.RoleSaveParam;
import com.company.cloud.user.modules.mgr.controller.req.RoleUpdateParam;
import com.company.cloud.user.modules.mgr.service.RoleMgrService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@RestController
@Service
public class RolePlatformRemoteServiceImpl implements RolePlatformRemoteService {

    @Autowired
    private RoleInfoService roleInfoService;
    @Autowired
    private RoleMgrService roleMgrService;
    @Autowired
    private UserPermissionCacheService userPermissionCacheService;
    @Autowired
    private RolePermissionInfoService rolePermissionInfoService;
    @Autowired
    private UserRoleInfoService userRoleInfoService;

    @Override
    public BaseClientResult<List<RoleModel>> roleList(RoleQueryRequest request) {
        try {
            ValidatorUtils.validate(request);
            List<RoleInfo> roleList= roleInfoService.list(new QueryWrapper<RoleInfo>()
                    .eq("is_sys", BaseConstant.YNEnum.YES.getCode()));
            List<RoleModel> data=new ArrayList<RoleModel>();
            if(!CollectionUtils.isEmpty(roleList)) {
                roleList.forEach(item->{
                    data.add(UserConvertUtils.getRoleModel(item));
                });
            }
            return BaseClientResult.success(data);
        } catch (Exception e) {
            return BaseClientResult.error(e);
        }
    }

    @Override
    public BaseClientResult<RoleModel> addRole(RoleAddRequest request) {
        try {
            ValidatorUtils.validate(request);
            LoginSimpleUserInfo userInfo=new LoginSimpleUserInfo();
            userInfo.setId(request.getOpUserId());
            userInfo.setIp(request.getOpIp());

            RoleSaveParam params=new RoleSaveParam();
            params.setCode(request.getCode());
            params.setName(request.getName());
            params.setCompanyNo(UserConstant.Sys_Company_No);
            params.setRemark(request.getRemark());
            params.setIsSys(BaseConstant.YNEnum.YES.getCode());
            params.setPermissionCodes(request.getPermissionCodes());
            RoleModel data = roleMgrService.save(params,userInfo);
            return BaseClientResult.success(data);
        } catch (Exception e) {
            return BaseClientResult.error(e);
        }
    }

    @Override
    public BaseClientResult<RoleModel> updateRole(RoleUpdateRequest request) {
        try {
            ValidatorUtils.validate(request);
            LoginSimpleUserInfo userInfo=new LoginSimpleUserInfo();
            userInfo.setId(request.getOpUserId());
            userInfo.setIp(request.getOpIp());

            RoleUpdateParam params=new RoleUpdateParam();
            params.setCode(request.getCode());
            params.setName(request.getName());
            params.setRemark(request.getRemark());
            params.setPermissionCodes(request.getPermissionCodes());
            RoleModel data= roleMgrService.update(params, userInfo);
            //重新初始化公司角色权限关系
            this.cacheReload(request.getCode());
            return BaseClientResult.success(data);
        } catch (Exception e) {
            return BaseClientResult.error(e);
        }
    }

    @Override
    public BaseClientResult<RoleModel> infoRole(RoleGet2DelRequest request) {
        try {
            ValidatorUtils.validate(request);
            RoleModel data=roleMgrService.get(request.getCode());
            return BaseClientResult.success(data);
        } catch (Exception e) {
            return BaseClientResult.error(e);
        }
    }

    @Override
    public BaseClientResult<String> delRole(RoleGet2DelRequest request) {
        try {
            ValidatorUtils.validate(request);
            LoginSimpleUserInfo userInfo=new LoginSimpleUserInfo();
            userInfo.setId(request.getOpUserId());
            userInfo.setIp(request.getOpIp());
            List<UserRoleInfo> userRoleList= roleMgrService.delete(request.getCode(),userInfo);
            //角色关联的用户退出
            if(!CollectionUtils.isEmpty(userRoleList)) {
                Set<Integer> userIds=new HashSet<Integer>();
                userRoleList.forEach(item->{
                    userIds.add(item.getUserId());
                });
                userPermissionCacheService.logoutUser(userIds);
            }
            //重新初始化公司角色权限关系
            this.cacheReload(request.getCode());
            return BaseClientResult.success();
        } catch (Exception e) {
            return BaseClientResult.error(e);
        }
    }

    @Override
    public BaseClientResult<String> reloadCompanyAuth(String companyNo) {
        try {
            userPermissionCacheService.initPermissionRoleCache(companyNo);
            return BaseClientResult.success();
        } catch (Exception e) {
            return BaseClientResult.error(e);
        }
    }


    private void cacheReload(String roleCode){
        List<UserRoleInfo> userRoleInfoList = userRoleInfoService.list(
                new QueryWrapper<UserRoleInfo>().select("company_no As companyNo")
                        .eq("role_code", roleCode)
                        .groupBy("company_no")
        );
        if(!CollectionUtils.isEmpty(userRoleInfoList)){
            for (UserRoleInfo userRoleInfo:userRoleInfoList){
                userPermissionCacheService.initPermissionRoleCache(userRoleInfo.getCompanyNo());
            }
        }
    }



}
